/* * Copyright 2013 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.apps.dashclock.gmail; import com.google.android.apps.dashclock.LogUtils; import com.google.android.apps.dashclock.api.DashClockExtension; import com.google.android.apps.dashclock.api.ExtensionData; import net.nurik.roman.dashclock.R; import android.accounts.Account; import android.accounts.AccountManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.preference.PreferenceManager; import android.util.Pair; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import static com.google.android.apps.dashclock.LogUtils.LOGD; import static com.google.android.apps.dashclock.LogUtils.LOGE; /** * Gmail unread count extension. */ public class GmailExtension extends DashClockExtension { private static final String TAG = LogUtils.makeLogTag(GmailExtension.class); public static final String PREF_ACCOUNTS = "pref_gmail_accounts"; public static final String PREF_LABEL = "pref_gmail_label"; private static final String ACCOUNT_TYPE_GOOGLE = "com.google"; //private static final String[] FEATURES_MAIL = {"service_mail"}; static String[] getAllAccountNames(Context context) { final Account[] accounts = AccountManager.get(context).getAccountsByType( GmailExtension.ACCOUNT_TYPE_GOOGLE); final String[] accountNames = new String[accounts.length]; for (int i = 0; i < accounts.length; i++) { accountNames[i] = accounts[i].name; } return accountNames; } private Set<String> getSelectedAccounts() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); final String[] accounts = GmailExtension.getAllAccountNames(this); Set<String> allAccountsSet = new HashSet<String>(); allAccountsSet.addAll(Arrays.asList(accounts)); return sp.getStringSet(PREF_ACCOUNTS, allAccountsSet); } @Override protected void onInitialize(boolean isReconnect) { super.onInitialize(isReconnect); if (!isReconnect) { Set<String> selectedAccounts = getSelectedAccounts(); String[] uris = new String[selectedAccounts.size()]; int i = 0; for (String account : selectedAccounts) { uris[i++] = GmailContract.Labels.getLabelsUri(account).toString(); // TODO: only watch the individual label's URI (GmailContract.Labels.URI) } addWatchContentUris(uris); } } @Override protected void onUpdateData(int reason) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); String labelCanonical = sp.getString(PREF_LABEL, "i"); Set<String> selectedAccounts = getSelectedAccounts(); if ("i".equals(labelCanonical)) { labelCanonical = GmailContract.Labels.LabelCanonicalNames.CANONICAL_NAME_INBOX; } else if ("p".equals(labelCanonical)) { labelCanonical = GmailContract.Labels.LabelCanonicalNames.CANONICAL_NAME_PRIORITY_INBOX; } int unread = 0; List<Pair<String, Integer>> unreadPerAccount = new ArrayList<Pair<String, Integer>>(); for (String account : selectedAccounts) { Cursor cursor = tryOpenLabelsCursor(account); if (cursor == null || cursor.isAfterLast()) { LOGD(TAG, "No Gmail inbox information found for account."); if (cursor != null) { cursor.close(); } continue; } while (cursor.moveToNext()) { if (labelCanonical.equals(cursor.getString(LabelsQuery.CANONICAL_NAME))) { int unreadThisAccount = cursor.getInt(LabelsQuery.NUM_UNREAD_CONVERSATIONS); unreadPerAccount.add(new Pair<String, Integer>(account, unreadThisAccount)); unread += unreadThisAccount; break; } } cursor.close(); } StringBuilder body = new StringBuilder(); for (Pair<String, Integer> pair : unreadPerAccount) { if (pair.second == 0) { continue; } if (body.length() > 0) { body.append("\n"); } body.append(pair.first).append(" (").append(pair.second).append(")"); } publishUpdate(new ExtensionData() .visible(unread > 0) .status(Integer.toString(unread)) .expandedTitle(getResources().getQuantityString( R.plurals.gmail_title_template, unread, unread)) .icon(R.drawable.ic_extension_gmail) .expandedBody(body.toString()) .clickIntent(new Intent(Intent.ACTION_MAIN) .setPackage("com.google.android.gm") .addCategory(Intent.CATEGORY_LAUNCHER))); } private Cursor tryOpenLabelsCursor(String account) { try { return getContentResolver().query( GmailContract.Labels.getLabelsUri(account), LabelsQuery.PROJECTION, null, // NOTE: the Labels API doesn't allow selections here null, null); } catch (Exception e) { // From developer console: "Permission Denial: opening provider com.google.android.gsf.. // From developer console: "SQLiteException: no such table: labels" // From developer console: "NullPointerException" LOGE(TAG, "Error opening Gmail labels", e); return null; } } private interface LabelsQuery { String[] PROJECTION = { GmailContract.Labels.NUM_UNREAD_CONVERSATIONS, GmailContract.Labels.URI, GmailContract.Labels.CANONICAL_NAME, }; int NUM_UNREAD_CONVERSATIONS = 0; int URI = 1; int CANONICAL_NAME = 2; } }